#include "Thread.h"
#include <iostream>
#include <cassert>

Thread::Thread(const ThreadFunc func, const std::string &name):
    _func{std::move(func)},
    _name{name.empty() ? "Thread" : name},
    _thread{},
    _started{false},
    _joined{false} {
    std::cout << name << " constructed.\n";
}

Thread::~Thread() {
    if (_started && !_joined) {
        _thread->detach();
    }
    std::cout << "thread " << _name << " destructed.\n";
}

void Thread::start() {
    assert(!_started);
    _started = true;
    try {
        _thread = std::make_unique<std::thread>([this](){
            _func();
        });
    }
    catch(const std::exception& e)
    {
        _started = false;
        std::cerr << e.what() << '\n';
    }
}

void Thread::join() {
    assert(_started);
    if(_joined) {
        std::cout << _name << " has alreayd started.\n";
        return;
    } else {
        std::cout << _name << " going to be joined\n";
    }
    assert(!_joined);
    _joined = true;
    if (!_thread->joinable()) {
        return;
    }
    _thread->join();
}
